package com.molichuxing.services.business.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.property.OperatorTypeEnum;
import com.molichuxing.services.business.convertor.Convert;
import com.molichuxing.services.business.dto.request.create.OrderRenegeCreateBizDto;
import com.molichuxing.services.business.dto.request.create.RecycleCarsCreateBizDto;
import com.molichuxing.services.business.dto.request.modify.*;
import com.molichuxing.services.business.dto.response.OrderRenegeBizDto;
import com.molichuxing.services.business.dto.response.OverdueBizDto;
import com.molichuxing.services.business.service.OrderExclusivelBizService;
import com.molichuxing.services.business.service.OrderRenegeBizService;
import com.molichuxing.services.business.service.OrderScheduleBizService;
import com.molichuxing.services.exception.OrderExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.request.create.OrderRenegeCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.OrderStatusFlowCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderRenegeCostModifyDto;
import com.molichuxing.services.infrastructure.dto.response.OrderExclusivelDto;
import com.molichuxing.services.infrastructure.dto.response.OrderNegotiateRenegeDto;
import com.molichuxing.services.infrastructure.dto.response.OrderRenegeDto;
import com.molichuxing.services.infrastructure.dto.response.OrderReturnDto;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 订单退租(违约)biz service
 *
 * @author zoumingyu
 * @date 2019年10月28日
 */
@Service("orderRenegeBizService")
public class OrderRenegeBizServiceImpl implements OrderRenegeBizService {
    private static final Logger logger = LoggerFactory.getLogger(OrderRenegeBizServiceImpl.class);

    @Resource
    private OrderExclusivelBizService orderExclusivelBizService;

    @Resource
    private OrderExclusivelService orderExclusivelService;

    @Resource
    private OrderRenegeService orderRenegeService;

    @Resource
    private OrderScheduleService orderScheduleService;

    @Resource
    private OrderReturnService orderReturnService;

    @Resource
    private OrderStatusFlowService orderStatusFlowService;

    @Resource
    private RecycleCarsService recycleCarsService;

    @Resource
    private OrderScheduleBizService orderScheduleBizService;

    /**
     * 查询订单退租信息
     *
     * @param orderCode 订单号
     * @param userId    用户id
     * @return
     */
    @Override
    public OrderRenegeBizDto getOrderRenege(Long orderCode, Integer userId) {
        OrderRenegeBizDto result = null;
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(orderCode);
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[getOrderRenege]查询订单退租信息异常，订单({})不存在", orderCode);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "查询订单退租信息异常，订单(" + orderCode + ")不存在");
        } else if (!orderExclusivel.getUserId().equals(userId)) {
            logger.error("[getOrderRenege]查询订单退租信息异常，订单({})用户({})异常", orderCode, userId);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "查询订单退租信息异常，订单(" + orderCode + ")不存在");
        }
        // 查询退租信息
        result = Convert.toOrderRenegeBizDto(orderRenegeService.getEffectiveRenege(orderCode));
        return result;
    }

    /**
     * 新增退租信息
     *
     * @param createBizDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean createRenege(OrderRenegeCreateBizDto createBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(createBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[createRenege]同意退租异常，订单({})不存在", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "同意退租异常，订单(" + createBizDto.getOrderCode() + ")不存在");
        }
        // 判断是否是安鹏征信
        if (OrderExclusivelTypeEnum.TYPE_TWO.equals(orderExclusivel.getType())) {
            logger.error("[createRenege]同意退租异常，订单({})是安鹏征信，不可退租", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "同意退租异常，订单(" + createBizDto.getOrderCode() + ")不可退租");
        }

        // 判断订单状态
        if (!(OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderExclusivel.getOrderStatus())
                || OrderExclusivelStatusEnum.TRADE_USE.equals(orderExclusivel.getOrderStatus()))) {
            // 只有待提车和用车中订单可以退租
            logger.error("[createRenege]同意退租异常，订单({})当前状态({})不可退租", createBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "同意退租异常，订单(" + createBizDto.getOrderCode() + ")当前状态(" + orderExclusivel.getOrderStatus().getName() + ")不可退租");
        }

        OrderExclusivelStatusEnum orderStatus = null;
        if (OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderExclusivel.getOrderStatus())) {
            // 待提车退租
            orderStatus = OrderExclusivelStatusEnum.RENEGE_UNPAID;
        } else {
            // 用车中退租
            orderStatus = OrderExclusivelStatusEnum.RENEGE_ACCEPTED;
        }

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(createBizDto, modifyDto);
        modifyDto.setModifiedType(OperatorTypeEnum.MEMBER.equals(createBizDto.getOperatorType())
                ? OrderStatusFlowModifiedTypeEnum.C_USER : OrderStatusFlowModifiedTypeEnum.B_USER);
        modifyDto.setOrderStatus(orderStatus);
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[createRenege]同意退租异常，订单({})状态修改状态失败", createBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "同意退租异常，订单(" + createBizDto.getOrderCode() + ")状态修改状态失败");
        }
        // 新增退租信息
        OrderRenegeCreateDto orderRenegeCreateDto = Convert.toOrderRenegeCreateDto(orderExclusivel);
        orderRenegeCreateDto.setRenegeType(createBizDto.getRenegeType());
        if (!orderRenegeService.create(orderRenegeCreateDto)) {
            logger.error("[createRenege]同意退租异常，订单({})新增退租信息失败", createBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "同意退租异常，订单(" + createBizDto.getOrderCode() + ")新增退租信息失败");
        }

        return true;
    }

    /**
     * 取消退租
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyCancel(OrderRenegeCancelModifyBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyCancel]取消退租异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "取消退租异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }

        // 查询退租信息
        OrderRenegeDto orderRenege = orderRenegeService.getRenege(modifyBizDto.getOrderCode(),
                OrderRenegeStatusEnum.RENEGE);
        if (orderRenege == null) {
            logger.error("[modifyCancel]取消退租异常，订单({})退租信息不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "取消退租异常，订单(" + modifyBizDto.getOrderCode() + ")退租信息不存在");
        }

        // 判断是否提车退租
        OrderExclusivelStatusEnum canCancelStatus = null;
        if (OrderExclusivelStatusEnum.TRADE_USE.equals(orderRenege.getBeforeOrderStatus())) {
            // 提车发起退租，待还车可取消
            canCancelStatus = OrderExclusivelStatusEnum.RENEGE_ACCEPTED;
        } else {
            // 未提车发起退租，收/退款可取消
            if (orderRenege.getPayee() != null) {
                logger.error("[modifyCancel]取消退租异常，订单({})已填写退款收款人", modifyBizDto.getOrderCode());
                throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                        "取消退租异常，订单(" + modifyBizDto.getOrderCode() + ")已填写退款收款人，不可退租");
            }
            canCancelStatus = OrderExclusivelStatusEnum.RENEGE_UNPAID;
        }

        // 判断订单状态
        if (!canCancelStatus.equals(orderExclusivel.getOrderStatus())) {
            logger.error("[modifyCancel]取消退租异常，订单({})当前状态({})不可取消", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "取消退租异常，订单(" + modifyBizDto.getOrderCode() + ")当前状态(" + orderExclusivel.getOrderStatus().getName()
                            + ")不可取消");
        }

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OperatorTypeEnum.MEMBER.equals(modifyBizDto.getOperatorType())
                ? OrderStatusFlowModifiedTypeEnum.C_USER : OrderStatusFlowModifiedTypeEnum.B_USER);
        modifyDto.setOrderStatus(orderRenege.getBeforeOrderStatus());
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyCancel]取消退租异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "取消退租异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
        }
        // 修改退租信息
        if (!orderRenegeService.modifyCancel(modifyBizDto.getOrderCode())) {
            logger.error("[modifyCancel]取消退租异常，订单({})修改退租信息失败", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "取消退租异常，订单(" + modifyBizDto.getOrderCode() + ")修改退租信息失败");
        }

        return true;
    }

    /**
     * 修改退租收款人信息
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyPayee(OrderRenegePayeeModifyBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyPayee]修改退租异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "修改退租异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }
        // 查询退租信息
        OrderRenegeDto orderRenege = orderRenegeService.getRenege(modifyBizDto.getOrderCode(),
                OrderRenegeStatusEnum.RENEGE);
        if (orderRenege == null) {
            logger.error("[modifyPayee]修改退租异常，订单({})退租信息不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "修改退租异常，订单(" + modifyBizDto.getOrderCode() + ")退租信息不存在");
        }
        // 退租前用车中状态，订单状态为 解除协议确认
        // 我司应收， 不改变订单状态
        // 我司应付， 订单状态变为 收/退款

        // 退租前待提车状态，订单状态为 收/退款，新增退租信息表收款人信息


        // 判断退租前订单状态
        if (OrderExclusivelStatusEnum.TRADE_USE.equals(orderRenege.getBeforeOrderStatus())) {
            // 退租前用车中状态，需要修改订单状态
            OrderModifyBizDto modifyDto = new OrderModifyBizDto();
            BeanUtils.copyProperties(modifyBizDto, modifyDto);
            modifyDto.setModifiedType(OperatorTypeEnum.MEMBER.equals(modifyBizDto.getOperatorType())
                    ? OrderStatusFlowModifiedTypeEnum.C_USER : OrderStatusFlowModifiedTypeEnum.B_USER);
            modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_UNPAID);
            modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
            if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
                logger.error("[modifyPayee]修改退租异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
                throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                        "修改退租异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
            }
        }
        // 修改退租信息
        if (!orderRenegeService.modifyPayee(Convert.toOrderRenegePayeeModifyDto(modifyBizDto))) {
            logger.error("[modifyPayee]修改退租异常，订单({})修改退租收款人信息失败", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "修改退租异常，订单(" + modifyBizDto.getOrderCode() + ")修改退租收款人信息失败");
        }

        return true;
    }

    /**
     * 发起收/付款
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyCost(OrderRenegeCostModifyBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyCost]发起收/付款异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "发起收/付款异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }
        // 判断订单状态
        if (!OrderExclusivelStatusEnum.RENEGE_SETTLEMENT.equals(orderExclusivel.getOrderStatus())) {
            // 只有财务结算中可以发起
            logger.error("[modifyCost]发起收/退款异常，订单({})当前状态({})不可发起收/退款", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "发起收/退款异常，订单(" + modifyBizDto.getOrderCode() + ")当前状态(" + orderExclusivel.getOrderStatus().getName() + ")不可发起收/退款");
        }

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.B_USER);
        modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_REFUND);
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyCost]发起收/退款异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "发起收/退款异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
        }
        // 修改退租信息
        OrderRenegeCostModifyDto costModifyDto = new OrderRenegeCostModifyDto();
        BeanUtils.copyProperties(modifyBizDto, costModifyDto);
        costModifyDto.setCostTime(LocalDateTime.now());
        if (!orderRenegeService.modifyCost(costModifyDto)) {
            logger.error("[modifyCost]发起收/退款异常，订单({})修改退租信息失败", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "发起收/退款异常，订单(" + modifyBizDto.getOrderCode() + ")修改退租信息失败");
        }

        return true;
    }

    /**
     * 退款完成
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyComplete(OrderRenegeCompleteModifyBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyComplete]退款完成异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退款完成异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }
        // 判断订单状态
        if (!OrderExclusivelStatusEnum.RENEGE_UNPAID.equals(orderExclusivel.getOrderStatus())) {
            // 只有退租退款中可以发起
            logger.error("[modifyComplete]退款完成异常，订单({})当前状态({})不可发起退款", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退款完成异常，订单(" + modifyBizDto.getOrderCode() + ")当前状态" +
                            "(" + orderExclusivel.getOrderStatus().getName() + ")不可发起退款");
        }

        // 查询退租信息
        OrderRenegeDto orderRenege = orderRenegeService.getRenege(modifyBizDto.getOrderCode(),
                OrderRenegeStatusEnum.RENEGE);

        checkOrderRenege(orderRenege);

        // 判断提车前退租，修改排期信息
        if (OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderRenege.getBeforeOrderStatus())) {
            // 修改排期计划-终止
            orderScheduleService.modifyCancel(modifyBizDto.getOrderCode(), OrderScheduleStatusEnum.NO);
        }

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.B_USER);
        modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_FINISH);
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyComplete]退款完成异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退款完成异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
        }
        // 修改退租信息
        if (!orderRenegeService.modifyComplete(modifyBizDto.getOrderCode())) {
            logger.error("[modifyComplete]退款完成异常，订单({})修改退租信息失败", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退款完成异常，订单(" + modifyBizDto.getOrderCode() + ")修改退租信息失败");
        }

        return true;
    }

    /**
     * 退租完成
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyFinish(OrderRenegeCompleteModifyBizDto modifyBizDto) {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyFinish]退租完成异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租完成异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }

        // 查询退租信息
        OrderRenegeDto orderRenege = orderRenegeService.getRenege(modifyBizDto.getOrderCode(),
                OrderRenegeStatusEnum.RENEGE);
        if (orderRenege == null) {
            logger.error("[modifyFinish]退租完成异常，订单({})退租信息不存在", orderRenege.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租完成异常，订单(" + orderRenege.getOrderCode() + ")退租信息不存在");
        }

        // 判断提车前退租，修改排期信息
        if (OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderRenege.getBeforeOrderStatus())) {
            // 修改排期计划-终止
            orderScheduleService.modifyCancel(modifyBizDto.getOrderCode(), OrderScheduleStatusEnum.NO);
        }

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.B_USER);
        modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_FINISH);
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyFinish]退租完成异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退租完成异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
        }
        // 修改退租信息
        if (!orderRenegeService.modifyComplete(modifyBizDto.getOrderCode())) {
            logger.error("[modifyFinish]退租完成异常，订单({})修改退租信息失败", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus().getName());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退租完成异常，订单(" + modifyBizDto.getOrderCode() + ")修改退租信息失败");
        }

        return true;
    }


    /**
     * 校验退租信息
     *
     * @param orderRenege
     * @return
     */
    private Boolean checkOrderRenege(OrderRenegeDto orderRenege) {
        if (orderRenege == null) {
            logger.error("[checkOrderRenege]退款完成异常，订单({})退租信息不存在", orderRenege.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退款完成异常，订单(" + orderRenege.getOrderCode() + ")退租信息不存在");
        }

        OrderRenegeCostTypeEnum costType = orderRenege.getCostType();
        BigDecimal costAmount = orderRenege.getCostAmount();
        String payee = orderRenege.getPayee();
        String bank = orderRenege.getBank();
        String bankNumber = orderRenege.getBankNumber();
        if (null == costType ||
                null == costAmount ||
                StringUtils.isBlank(payee) ||
                StringUtils.isBlank(bank) ||
                StringUtils.isBlank(bankNumber)) {
            logger.error("[checkOrderRenege]退款完成异常，订单({})退租收款人信息不存在", orderRenege.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退款完成异常，订单(" + orderRenege.getOrderCode() + ")退租收款人信息不存在");
        }

        return true;
    }

    /**
     * 退租还车修改信息-大屏还车
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyReturnCar(OrderReturnCarModifyBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyReturnCar]退租还车异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租还车异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }
        // 判断订单状态
        if (!OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(orderExclusivel.getOrderStatus())) {
            // 只有待还车订单可以退租还车
            logger.error("[modifyReturnCar]退租还车异常，订单({})当前状态({})不可还车", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(), "退租还车异常，订单("
                    + modifyBizDto.getOrderCode() + ")当前状态(" + orderExclusivel.getOrderStatus().getName() + ")不可还车");
        }

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.B_USER);
        modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_SETTLEMENT);
        modifyDto.setPreOrderStatus(OrderExclusivelStatusEnum.RENEGE_ACCEPTED);
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyReturnCar]退租还车异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退租还车异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
        }

        // 新增还车信息
        orderReturnService.create(Convert.toOrderReturnCreateDto(modifyBizDto, orderExclusivel));

        // 修改排期计划-终止
        orderScheduleService.modifyCancel(modifyBizDto.getOrderCode(), OrderScheduleStatusEnum.NO);

        return true;
    }

    /**
     * 退租收车修改信息-op收车
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean createRecycleCar(RecycleCarsCreateBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[createRecycleCar]退租收车异常，订单({})不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租收车异常，订单(" + modifyBizDto.getOrderCode() + ")不存在");
        }

        // 待收车订单修改订单状态
        if (OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(orderExclusivel.getOrderStatus())) {
            OrderModifyBizDto modifyDto = new OrderModifyBizDto();
            BeanUtils.copyProperties(modifyBizDto, modifyDto);
            modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.B_USER);
            modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_SETTLEMENT);
            modifyDto.setPreOrderStatus(OrderExclusivelStatusEnum.RENEGE_ACCEPTED);
            if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
                logger.error("[createRecycleCar]退租收车异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
                throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                        "退租收车异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
            }
        }

        // 查询还车表，判断是否已经还车/收车
        OrderReturnDto orderReturn = orderReturnService.getOrderReturnAll(modifyBizDto.getOrderCode());
        if (orderReturn == null) {
            // 新增退租收车记录表
            recycleCarsService.create(Convert.toRecycleCarsCreateDto(modifyBizDto, orderExclusivel));

            // 新增还车信息
            orderReturnService.create(Convert.toOrderReturnCreateDto(modifyBizDto, orderExclusivel));

        } else if (RecycleStateEnum.FAIL.getValue() == orderReturn.getRecycleState()) {
            // 判断收车状态
            if (RecycleStateEnum.FAIL.equals(modifyBizDto.getRecycleState())) {
                return true;
            }
            // 新增退租收车记录表
            recycleCarsService.create(Convert.toRecycleCarsCreateDto(modifyBizDto, orderExclusivel));

            // 修改还车信息
            orderReturnService.modifyRecycle(Convert.toOrderRecycleCarsModifyDto(modifyBizDto));
        }

        // 判断是否收车结束
        if (RecycleStateEnum.FAIL.getValue() < modifyBizDto.getRecycleState().getValue()
                && !OrderExclusivelStatusEnum.LAWSUIT.equals(orderExclusivel.getOrderStatus())) {
            // 修改排期计划-终止
            orderScheduleService.modifyCancel(modifyBizDto.getOrderCode(), OrderScheduleStatusEnum.NO);

            // 查询逾期信息
            OverdueBizDto overdue = orderScheduleBizService.getOverdue(orderExclusivel.getOrderCode(), LocalDate.now());
            if (overdue != null) {
                // 修改还车信息
                orderRenegeService.modifyOverdue(orderExclusivel.getOrderCode(), overdue.getOverdueDays(), overdue.getOverdueNum());
            }

        }


        return true;
    }

    /**
     * 退租缴费支付修改
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyPay(OrderPayModifyBizDto modifyBizDto) {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyPay]退租缴费支付修改异常，订单({})不存在", modifyBizDto.getOrderCode());
            return false;
        }

        // 退租缴费同时完成了 解除协议确认 和 收款 操作，添加流转信息
        OrderStatusFlowCreateDto orderStatusFlowCreateDto = new OrderStatusFlowCreateDto();
        BeanUtils.copyProperties(modifyBizDto, orderStatusFlowCreateDto);
        orderStatusFlowCreateDto.setOrderCode(modifyBizDto.getOrderCode());
        orderStatusFlowCreateDto.setOrderModifiedTime(LocalDateTime.now());
        orderStatusFlowCreateDto.setOrderModifiedType(OrderStatusFlowModifiedTypeEnum.C_USER.getValue());
        orderStatusFlowCreateDto.setOrderUserId(modifyBizDto.getOperateId());
        orderStatusFlowCreateDto.setOrderUserName(modifyBizDto.getOperateName());
        // 新增解除协议确认
        orderStatusFlowCreateDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_REFUND.getValue());
        orderStatusFlowService.createOrderStatusFlow(orderStatusFlowCreateDto);
        // 新增收/退款
        orderStatusFlowCreateDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_UNPAID.getValue());
        orderStatusFlowService.createOrderStatusFlow(orderStatusFlowCreateDto);

        // 修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.C_USER);
        modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_FINISH);
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyPay]退租缴费支付异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            return false;
        }
        // 修改退租信息
        if (!orderRenegeService.modifyComplete(modifyBizDto.getOrderCode())) {
            logger.error("[modifyPay]退租缴费支付异常，订单({})修改退租信息失败", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus());
            return false;
        }
        return true;
    }

    /**
     * 退租解除协议确认修改
     *
     * @param modifyBizDto
     * @return
     * @throws BizException
     * @throws Exception
     */
    @Override
    public Boolean modifyContractRescission(OrderRenegeContractRescissionModifyBizDto modifyBizDto) throws BizException, Exception {
        // 根据订单号，查询订单信息（只有专属订单有退租）
        OrderExclusivelDto orderExclusivel = orderExclusivelService.getOrderExclusivel(modifyBizDto.getOrderCode());
        if (orderExclusivel == null) {
            // 订单不存在
            logger.error("[modifyContractRescission]退租缴费支付修改异常，订单({})不存在", modifyBizDto.getOrderCode());
            return false;
        }
        // 判断订单状态
        if (!OrderExclusivelStatusEnum.RENEGE_REFUND.equals(orderExclusivel.getOrderStatus())) {
            logger.error("[modifyContractRescission]退租解除协议确认异常，订单({})当前状态({})不可还车", modifyBizDto.getOrderCode(),
                    orderExclusivel.getOrderStatus());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(), "退租解除协议确认异常，订单("
                    + modifyBizDto.getOrderCode() + ")当前状态(" + orderExclusivel.getOrderStatus().getName() + ")不确认");
        }

        // 查询退租信息
        OrderRenegeDto orderRenege = orderRenegeService.getRenege(modifyBizDto.getOrderCode(),
                OrderRenegeStatusEnum.RENEGE);
        if (orderRenege == null) {
            logger.error("[modifyContractRescission]退租解除协议确认异常，订单({})退租信息不存在", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(),
                    "退租解除协议确认异常，订单(" + modifyBizDto.getOrderCode() + ")退租信息不存在");
        }
        // 判断费用类型
        if (OrderRenegeCostTypeEnum.INCOME.equals(orderRenege.getCostType())) {
            // 我司应收，则需要等待支付完成才修改
            logger.info("订单({})退租，我司应收需要等待支付完成才完成解除协议确认", modifyBizDto.getOrderCode());
            return true;
        }

        // 提车订单-我司应付 和 为提车订单，修改订单状态
        OrderModifyBizDto modifyDto = new OrderModifyBizDto();
        BeanUtils.copyProperties(modifyBizDto, modifyDto);
        modifyDto.setModifiedType(OrderStatusFlowModifiedTypeEnum.C_USER);
        modifyDto.setOrderStatus(OrderExclusivelStatusEnum.RENEGE_UNPAID);
        modifyDto.setPreOrderStatus(orderExclusivel.getOrderStatus());
        if (!orderExclusivelBizService.modifyExclusivelStatus(modifyDto)) {
            logger.error("[modifyContractRescission]退租解除协议确认异常，订单({})状态修改状态失败", modifyBizDto.getOrderCode());
            throw new BizException(OrderExceptionCodeEnum.STATUS_ERROR.getCode(),
                    "退租解除协议确认异常，订单(" + modifyBizDto.getOrderCode() + ")状态修改状态失败");
        }

        return true;
    }

    /**
     * 查询协商退租列表
     *
     * @param params   查询参数
     * @param pageNum  页数
     * @param pageSize 每页条数
     * @return Paged
     */
    @Override
    public Paged<OrderNegotiateRenegeDto> getNegotiateRenegePaged(Map<String, Object> params, int pageNum, int pageSize) {
        Paged<OrderNegotiateRenegeDto> result = orderRenegeService.getNegotiateRenegePaged(params, pageNum, pageSize);

        if (result.getTotal() == 0 || result.getList() == null) {
            return result;
        }
        for (OrderNegotiateRenegeDto orderNegotiateRenegeDto : result.getList()) {
            if (RecycleStateEnum.NOT.getValue() == orderNegotiateRenegeDto.getRecycleState()
                    || RecycleStateEnum.FAIL.getValue() == orderNegotiateRenegeDto.getRecycleState()) {
                // 计算逾期信息
                OverdueBizDto overdue = orderScheduleBizService.getOverdue(orderNegotiateRenegeDto.getOrderCode(), LocalDate.now());
                if (overdue == null) {
                    continue;
                }
                orderNegotiateRenegeDto.setOverdueNum(overdue.getOverdueNum());
                orderNegotiateRenegeDto.setOverdueDays(overdue.getOverdueDays());
            }
        }

        return result;
    }
}
